package com.lucene;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 创建索引
 *
 * @author HuTongFu
 * @since 2018/1/3
 */
public class IndexManagerTest {

    @Test
    public void IndexCreateTest() throws IOException {

        //创建文档列表，保存多个Document
        List<Document> documentList = new ArrayList<>();

        //指定文件所在的目录
        File dir = new File("D:\\workspace\\lucene\\file");

        for (File file : dir.listFiles()) {
            //文件名
            String fileName = file.getName();
            //文件内容
            String fileContext = FileUtils.readFileToString(file);
            //文件大小
            Long fileSize = FileUtils.sizeOf(file);

            //文档对象，文件系统中的一个文件就是一个Document对象
            Document document = new Document();
            //创建文档的域.第一个参数【域名】、第二个参数【域值】、第三个参数【是否存储】
            /*TextField nameField = new TextField("fileName", fileName, Field.Store.YES);
            TextField contextField = new TextField("fileContext", fileContext, Field.Store.YES);
            TextField sizeField = new TextField("fileSize", String.valueOf(fileSize), Field.Store.YES);*/

            //是否分词：是，因为要索引，并且它不是一个整体，分词有意义
            //是否索引：是，因为要通过它进行搜索
            //是否存储：是，因为要直接在页面上显示
            TextField nameField = new TextField("fileName", fileName, Field.Store.YES);

            //是否分词：是，因为要根据内容进行搜索，且分词有意义
            //是否索引：是，因为要根据它进行搜索
            //是否存储：可以是也可以不是，如果不是则搜索完内容就提取不出来
            TextField contextField = new TextField("fileContext", fileContext, Field.Store.NO);

            //是否分词：是，因为数字要对比，搜索文档的时候可以搜索大小，lucene内部对数字进行了分词算法
            //是否索引：是，因为要根据大小进行搜索
            //是否存储：是，因为要显示文档大小
            LongField sizeField = new LongField("fileSize", fileSize, Field.Store.YES);

            //将所有的域放入document对象中
            document.add(nameField);
            document.add(contextField);
            document.add(sizeField);

            //将document存放到documentList 中
            documentList.add(document);

        }

        //创建分词器，StandardAnalyzer标准分词器，对中文是单字分词，对英文分词效果很好
        //Analyzer analyzer = new StandardAnalyzer();
        //创建分词器，IKAnalyzer中文分词器
        Analyzer analyzer = new IKAnalyzer();
        //创建索引和文档存储的目录
        Directory directory = FSDirectory.open(new File("D:\\workspace\\lucene\\writer"));
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        //创建索引和文档写对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        //将文档加入到索引和文档的写对象中
        documentList.forEach(document -> {
            try {
                indexWriter.addDocument(document);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        //提交
        indexWriter.commit();
        //关闭流
        indexWriter.close();
    }


    @Test
    public void indexDelTest() throws IOException {

        //创建分词器，IkAnalyzer中文分词器
        Analyzer analyzer = new IKAnalyzer();

        //创建索引和文档的存储目录
        Directory directory = FSDirectory.open(new File("D:\\workspace\\lucene\\writer"));
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);

        //创建索引和文档写对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        //删除所有索引
//        indexWriter.deleteAll();

        //根据名称删除索引，Term是词元，就是一个词，第一个参数【域名】，第二个参数【要删除含有此关键词的数据】
        indexWriter.deleteDocuments(new Term("fileContext", "测试"));

        indexWriter.commit();
        indexWriter.close();

    }

    /**
     * 更新就是根据传入的Term进行搜索，如果搜索到结果，则删除该Document且将更新的内容重新生成一个Document对象
     * 如果没有搜索到结果，那么将更新的内容直接添加一个新的Document对象。
     * @throws IOException
     */
    @Test
    public void indexUpdateTest() throws IOException {
        //创建分词器，IkAnalyzer中文分词器
        Analyzer analyzer = new IKAnalyzer();

        //创建索引和文档的存储目录
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        Directory directory = FSDirectory.open(new File("D:\\workspace\\lucene\\writer"));

        //创建索引和文档的写对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        //根据文件名称进行更新
        Term term = new Term("fileName", "update");

        //更新的对象Doc
        Document document = new Document();
        document.add(new TextField("fileName", "更新", Field.Store.YES));
        document.add(new TextField("fileContext", "我更新了", Field.Store.NO));
        document.add(new LongField("fileSize", 100L, Field.Store.YES));

        //更新
        indexWriter.updateDocument(term, document);

        indexWriter.commit();
        indexWriter.close();
    }

}
